<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=utf-8>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <script src="https://cdn.jsdelivr.net/gh/eduardolundgren/tracking.js/build/tracking-min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/eduardolundgren/tracking.js/build/data/face-min.js"></script>
    <script type="text/javascript" src="{__SGHOME_PATH}js/jquery-3.1.1.min.js"></script>
</head>
<style>
    body {
        margin: 0;
        padding: 0;
        text-align: center;
    }
    .video-wrapper {
        position: relative;
        height: 100vh;
    }
    .wrapper {
        position: absolute;
        width: 100%;
        height: 100%;
        z-index: 1000;
    }
    #video {
        position: relative;
        width: 100%;
        height: 100%;
        object-fit: cover;
        z-index: 1;
        background-repeat: no-repeat;
        background-size: 100% 100%;
    }
    .img-wrapper {
        height: 100%;
        width: 100%;
        opacity: .4;
    }
    .canvas-wrapper {
        margin: 0 auto;
        width: 320px;
    }
    #imgView {
        margin: 0 auto;
        width: 320px;
    }
    #capture {
        position: absolute;
        bottom: 20px;
        left: calc(50% - 50px);
        height: 100px;
        width: 100px;
        padding: 4px;
        border-radius: 50%;
    }
    #closeBtn {
        position: absolute;
        top: 0px;
        left: 0px;
        padding: 8px 10px;
        border-radius: 2px;
    }
    #openBtn {
        position: absolute;
        top: 0px;
        right: 0px;
        padding: 8px 10px;
        border-radius: 2px;
    }
    #imgTip {
        position: absolute;
        width: 200px;
        /* margin: 0 auto; */
        top: 100px;
        left: 50%;
        margin-left: -90px;
        color: #fff;
    }
    .rect {
        border: 2px solid #a64ceb;
        left: -1000px;
        position: absolute;
        top: -1000px;
        z-index: 1100;
    }

    video::-webkit-media-controls-start-playback-button {
        display: none;
    }

    video::-moz-media-controls-play-button {
        display: none;
    }

    video::-o-media-controls-play-button {
        display: none;
    }

    video::-ms-media-controls-play-button {
        display: none;
    }

</style>
<body>
<div class="video-wrapper">
    <!-- 视频遮罩层 -->
    <div class="wrapper">
        <div id="imgTip"><h2>正在检测人脸中...</h2></div>
        <img class="img-wrapper" id="imgWrap" src="{__SGHOME_PATH}images/face-wrapper.jpg"/>
        <!--拍照按钮-->
        <button id="capture" style="display:none;">拍照</button>
    </div>
    <!-- video用于显示媒体设备的视频流，自动播放 -->
    <video id="video" style="display: none;" muted
           x5-playsinline="true"
           playsinline="true"
           webkit-playsinline="true"
           x-webkit-airplay="true"
           x5-video-orientation="portraint" ></video>
</div>
<!-- 描绘video截图 -->
<h1>Canvas Info</h1>
<div class="canvas-wrapper">
    <canvas id="canvas" width="320" height="480"></canvas>
</div>
<h1>Img Info</h1>
<!-- canvas 转换成 img -->
<div id="imgView"></div>
<!-- 错误提示，用于移动端观察 -->
<h1>Error Info</h1>
<div id="errorTip"></div>
<!-- 设备信息 -->
<h1>Device Info</h1>
<div id="device" style="text-align: center;"></div>
</body>

<script type="text/javascript">
    // 定义全局变量
    const video = document.getElementById("video");
    const canvas = document.getElementById("canvas");
    const context = canvas.getContext("2d");
    const imgView = document.getElementById("imgView");
    const errorTip = document.getElementById("errorTip");
    const imgWrap = document.getElementById('imgWrap');
    const device = document.getElementById('device');
    const capture = document.getElementById('capture');
    const imgTip = document.getElementById('imgTip');
    const closeBtn = document.getElementById('closeBtn');

    // 判断是否拍照
    let flag = 0
    let tipFlag = 0
    // 视频流实例
    let streamIns = null;

    // 新建一个tracker实例
    const tracker = new tracking.ObjectTracker(['face']); // 可选 face, eye, mouth, 需要引入相应的js

    // 设置步长
    tracker.setStepSize(1.7);

    // 绑定监听方法
    tracker.on('track', handleTracked);

    // 开始追踪
    tracking.track('#video', tracker);

    const SECOND = 1000
    // 10s后移除监听
    setTimeout(removeTracker, 10 * SECOND);

    // 处理追踪事件
    function handleTracked(event) {
        if (event.data.length === 0) {
            // 没有检测到
            console.log('没有检测到人脸');
        } else {
            // 提示用户已经检测到人脸
            if(!tipFlag) {
                imgTip.innerText = '检测人脸成功，正在拍照，请保持不动2秒！';
            }

            // 1秒后拍照，仅拍一次
            if(!flag) {
                flag = 1;
                setTimeout(() => {
                    // 模拟btn点击事件
                    capture.click();
                    imgTip.innerText = '拍照完成！';
                    tipFlag = 1
                }, 2000);
            }

            // 人脸数据点阵处理
            event.data.forEach(window.plot)
        }
    }

    // 移除监听事件
    function removeTracker() {
        errorTip.innerText = '移除追踪'
        tracker.removeListener('track', handleTracked)
    }

    // 绘制追踪框
    window.plot = function({x, y, width: w, height: h}) {
        // 创建框对象
        const rect = document.createElement('div');
        document.querySelector('.video-wrapper').appendChild(rect);
        rect.classList.add('rect');
        rect.style.width = w + 'px';
        rect.style.height = h + 'px';
        rect.style.left = (video.offsetLeft + x) + 'px';
        rect.style.top = (video.offsetTop + y) + 'px';

        // 显示追踪点到页面上
        device.innerText = "x:" + x + "y:" + y + "h:" +h + "w:" + w;
    };

    // 关闭摄像
    function closeStream() {
        errorTip.innerText = "我点击了关闭；视频流对象：" + streamIns
        try {
            streamIns.enabled = false;
            streamIns.getTracks()[0].stop();
            streamIns.getVideoTracks()[0].stop();
            closeBtn.style.display = 'none';
            openBtn.style.display = 'block';
        } catch(e) {
            throw new Error(e);
        }
    }

    // 开启摄像
    function openStream() {
        window.location.reload()
    }

    // 访问用户媒体设备的兼容方法
    function getUserMedia(constrains,success,error){
        if(navigator.mediaDevices.getUserMedia){
            //最新标准API
            navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error);
        } else if (navigator.webkitGetUserMedia){
            //webkit内核浏览器
            navigator.webkitGetUserMedia(constrains).then(success).catch(error);
        } else if (navigator.mozGetUserMedia){
            //Firefox浏览器
            navagator.mozGetUserMedia(constrains).then(success).catch(error);
        } else if (navigator.getUserMedia){
            //旧版API
            navigator.getUserMedia(constrains).then(success).catch(error);
        }
    }

    // 成功的回调函数
    function success(stream){
        streamIns = stream
        //兼容webkit内核浏览器
        const CompatibleURL = window.URL || window.webkitURL;
        //将视频流设置为video元素的源
        video.srcObject = stream;
        // 播放视频
        video.play();
        video.style.display = 'block';
    }

    // 异常的回调函数
    function error(error){
        video.style.display = 'none';
        errorTip.innerText = '访问用户媒体设备失败：' + error;
        throw new Error("访问用户媒体设备失败：" + error.name + error.message);
    }

    // 保存成png格式的图片
    function saveAsPNG(canvas) {
        return canvas.toDataURL("image/png");
    }

    // canvas to Image
    function convertCanvasToImage(canvas) {
        var image = new Image();
        image.src = canvas.toDataURL("image/png");
        return image;
    }

    // 注册拍照按钮的单击事件
    document.getElementById("capture").addEventListener("click",function(){
        //绘制画面
        context.drawImage(video,0,0,320,480);
        // 保持图片为base64格式
        const imgUrl = saveAsPNG(canvas);
        // 显示图片
        imgView.appendChild(convertCanvasToImage(canvas));
    });

    $(function (){
        if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
            //调用用户媒体设备，访问摄像头
            getUserMedia({
                video: {
                    width: 1920,
                    height: 1080,
                    facingMode: "user" // 前置优先
                }
            }, success, error);
        } else {
            errorTip.innerText = '你的浏览器不支持访问用户媒体设备';
            alert("你的浏览器不支持访问用户媒体设备");
        }

    });
</script>

</html>